package com.esir.harmony.util;


import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.util.HashMap;
import java.util.Locale;


public class LogUtils {
    private static String APP_TAG = "LogUtils";

    private static final HashMap<String, HiLogLabel> sCachedTag = new HashMap<>();
    private static JsonFormatter sJsonFormatter = new DefaultFormatter();

    private LogUtils() {
        throw new UnsupportedOperationException(this.getClass().getSimpleName() + " cannot be instantiated");
    }

    public static void Init(String appTag, JsonFormatter formatter) {
        APP_TAG = appTag;
        sJsonFormatter = formatter;
    }

    public static void i(String message) {
        i(APP_TAG, message);
    }

    public static void d(String message) {
        d(APP_TAG, message);
    }

    public static void w(String message) {
        w(APP_TAG, message);
    }

    public static void e(String message) {
        e(APP_TAG, message);
    }

    public static void v(String message) {
        v(APP_TAG, message);
    }

    public static void wtf(String message) {
        wtf(APP_TAG, message);
    }

    public static void json(String message) {
        json(APP_TAG, message);
    }

    public static void i(String tag, String message) {
        HiLog.info(buildTag(tag), buildMessage(message));
    }

    public static void d(String tag, String message) {
        HiLog.debug(buildTag(tag), buildMessage(message));
    }

    public static void w(String tag, String message) {
        HiLog.warn(buildTag(tag), buildMessage(message));
    }

    public static void e(String tag, String message) {
        HiLog.error(buildTag(tag), buildMessage(message));
    }

    public static void v(String tag, String message) {
        HiLog.fatal(buildTag(tag), buildMessage(message));
    }

    public static void wtf(String tag, String message) {
        HiLog.info(buildTag(tag), buildMessage(message));
    }

    public static void json(String tag, String content) {
        HiLog.fatal(buildTag(tag), buildMessage(formatJson(content)));
    }

    private static HiLogLabel buildTag(String tag) {
        return buildTag(0, tag);
    }

    private static HiLogLabel buildTag(int domain, String tag) {
        String key = String.format(Locale.US, "%s@%s", tag, Thread.currentThread().getName());

        if (!sCachedTag.containsKey(key)) {
            if (APP_TAG.equals(tag)) {

                HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, domain,
                        String.format(Locale.US, "|%s|%s|",
                                tag,
                                Thread.currentThread().getName()));
                sCachedTag.put(key, LABEL);
            } else {

                HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, domain,
                        String.format(Locale.US, "|%s_%s|%s|",
                                APP_TAG,
                                tag,
                                Thread.currentThread().getName()
                        ));
                sCachedTag.put(key, LABEL);
            }
        }

        return sCachedTag.get(key);
    }

    private static String buildMessage(String message) {
        StackTraceElement[] traceElements = Thread.currentThread().getStackTrace();

        if (traceElements == null || traceElements.length < 4) {
            return message;
        }
        StackTraceElement traceElement = traceElements[4];

        return String.format(Locale.US, "%s.%s(%s:%d) %s",
                traceElement.getClassName().substring(traceElement.getClassName().lastIndexOf(".") + 1),
                traceElement.getMethodName(),
                traceElement.getFileName(),
                traceElement.getLineNumber(),
                message
        );
    }

    private static String formatJson(String content) {
        return String.format(Locale.US, "\n%s", sJsonFormatter.formatJson(content));
    }

    public interface JsonFormatter {
        String formatJson(String content);
    }

    private static class DefaultFormatter implements JsonFormatter {
        @Override
        public String formatJson(String content) {
            return content;
        }
    }
}